home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / int24.aqm / int24.asm
Assembly Source File  |  1986-09-18  |  10KB  |  267 lines

  1. ;*****************************************************************************
  2. ;* THIS IS A COMMENTED VERSION OF THE MS-DOS 2.1 INT24H CRITICAL ERROR
  3. ;*   HANDLER. THE ASSEMBLER WAS GENERATED BY DEBUG'S UNASSEMBLE COMMAND.
  4. ;* Marc Adler - Magma Software Systems
  5. ;*****************************************************************************
  6.  
  7. 0534:04E2       INTERRUPT 24H handler (critical errors)
  8. ; Save registers and enable further interrupts
  9.         STI
  10.         PUSH   DS
  11.         PUSH   ES
  12.         PUSH   DI
  13.         PUSH   CX
  14.         PUSH   AX
  15.  
  16. ; BP:SI points to the device header. AH contains the device info.
  17. ; Lower half of DI contains the error type.
  18.         MOV    DS,BP            ; DS now references the device header
  19.         MOV    AX,[SI+04]       ; AX has device info - bit 15 is 1 if device
  20.         MOV    CS:[080F],AH     ;  is a char device - 0 if it's a block device
  21.  
  22. ; Transfer the device name to an area at CS:07B7
  23.         PUSH   CS
  24.         POP    ES
  25.         MOV    DI,07B7
  26.         MOV    CX,0008
  27.         ADD    SI,0A
  28.         REPZ
  29.         MOVSB
  30.  
  31. ; Restore the saved registers
  32.         POP    AX
  33.         POP    CX
  34.         POP    DI
  35.         POP    ES
  36.  
  37. ; The following call puts the contents at PSP[18H] into [930]. Then it 
  38. ; copies the contents of PSP[1AH] into PSP[18H].
  39. ; DOS seems to keep a table of file handles from 18H to 2BH (undocumented).
  40. ; The file handle at 18H is the handle for standard input, and the handle
  41. ; at 1AH is the handle for standard output. Location 930 seems to be a
  42. ; temp storage location to hold file handle 0.
  43.         CALL   04C6             ; int21(51H);  [930] = [018];  [018] = [01A];
  44.  
  45. ; Establish addressability for the DS register
  46.         PUSH   CS               ; DS = this segment
  47.         POP    DS
  48.  
  49. ; Output a carriage return
  50.         PUSH   DX
  51.         CALL   0632             ; put_cr();
  52.         POP    DX
  53.  
  54. ; Poke the offending drive's letter into the error message
  55.         ADD    AL,41            ; AL += 'A'
  56.         MOV    [07AC],AL        ; Put offending drive's letter in [07AC]
  57.  
  58. ; If the error isn't a disk error, and the offending device is a block
  59. ; device, then we must have a bad FAT table.
  60.         TEST   AH,80            ; if the error is not a disk error
  61.         JE     0521
  62.         TEST   BYTE PTR [080F],80 ; if device is a block device
  63.         JNE    0521
  64.         JMP    05D9             ;     fat_bad()
  65.  
  66. ; Unreachable code (?)
  67.         MOV    SI,0793          ; next 3 stmts are unreachable
  68.         TEST   AH,01
  69.         JE     052C
  70.  
  71. ; Poke either "read" or "writ" into the error message
  72. 0521:   MOV    SI,0797
  73.         LODSW
  74.         MOV    [079E],AX        ; [079E] = [0797]   "wr"
  75.         LODSW
  76.         MOV    [07A0],AX        ; [07A0] = [0799]   "it"
  77.  
  78. ; Use the error code as an index into an array of error message pointers,
  79. ; and print the error message.
  80. ; Remember that low half of DI contains the error code
  81. 052C:   AND    DI,00FF          ; if (DI > 12)
  82.         CMP    DI,0C
  83.         JBE    0540
  84.         MOV    DI,000C          ;   DI = 12;
  85. 0540:   MOV    [092E],DI        ; use err code as index into a message array
  86.         SHL    DI,1             ; There are 13 possible msgs, 0-12
  87.         MOV    DI,[DI+06E7]     ; [06E7-06FF] indexes the message
  88.         XCHG   DX,DI
  89.         CALL   0635             ; print the message
  90.         MOV    DX,079B          ; print "reading" or "writing"
  91.         CALL   0635
  92.         TEST   BYTE PTR [080F],80;if ([80F] & 0x80)   /* char device */
  93.         JE     0565             ; {
  94.         MOV    DX,07AF          ;   print "device"
  95.         MOV    AH,09            ; }
  96.         INT    21
  97.         JMP    0577             ; else                /* disk device */
  98. 0565:   MOV    DX,07A5          ; {
  99.         CALL   0635             ;   print "drive <d>"
  100.         CMP    BYTE PTR [0932],0;   if ([0932] != 0)   /* What's 932? */
  101.         JE     0577             ;   {
  102.         CALL   05EF             ;     Restore orginal file handle 0
  103.         JMP    05E9             ;     command_bad();
  104.                                 ;   }
  105.                                 ; }
  106.  
  107. ; Print the "Abort, Retry, Ignore" message, and get the user's response
  108. 0577:   MOV    DX,07F9          ; print 'Abort, Retry, Ignore' message
  109.         CALL   0635
  110. 057D:   MOV    AX,0C01          ; get user response
  111.         INT    21
  112.         CALL   0632
  113.  
  114. ; Process the user's response
  115.         OR     AL,20            ; convert response to lower case
  116.         MOV    AH,00            ; AH holds code (0,1,2) to return to DOS
  117.         CMP    AL,69            ; did user specify 'i' (ignore) ?
  118.         JE     05D0             ; YES - return to DOS
  119.  
  120.         INC    AH               ; retry's return code is 1
  121.         CMP    AL,72            ; user specified 'r' (retry) ?
  122.         JE     05D0             ; YES - return to DOS
  123.  
  124.         INC    AH               ; abort's return code is 2
  125.         CMP    AL,61            ; user specified 'a' (abort) ?
  126.         JNE    0577             ; NO - reprint msg & get response
  127.  
  128. ; At this point, the user specified the 'ABORT' response
  129. abort()
  130. {
  131. 0599:   XOR    DX,DX
  132.         XCHG   [0A77],DL                ; DL = [0A77];  [0A77] = 0;
  133.         OR     DL,DL                    ; if (DL != 0)
  134.         JE     05B0                     ; {
  135.         CMP    WORD PTR [0973],00       ;   if ([0973] != 0)
  136.         JE     05B0                     ;     [0973] = 0xFFFF;
  137.         MOV    [0973],FFFF              ; }
  138. 05B0:   CMP    WORD PTR [092E],00       ; if (errcode == 0 || errcode == 2)
  139.         JE     05BE                     ; {   write prot      drv not ready
  140.         CMP    WORD PTR [092E],02
  141.         JNE    05D0
  142. 05BE:   MOV    [0977],00                ;   [0977] = 0;
  143.         CMP    WORD PTR [0973],00       ;   if ([0973] != 0)
  144.         JE     05D0                     ;     [0973] = 0xFFFF;
  145.         MOV    [0973],FFFF              ; }
  146.  
  147. ; THE BIG RETURN TO DOS!!!!!
  148. 05D0:   MOV    AL,AH                    ; AL has return code (0,1,2)
  149.         MOV    DX,DI
  150. 05D4:   CALL   05EF                     ; Restore orginal file handle 0
  151.         POP    DS
  152.         IRET                            ; Return to DOS
  153. }
  154.  
  155. fat_bad()
  156. {
  157. 05D9:   MOV    DX,0810                  ; print "File allocation table bad"
  158.         CALL   0635
  159.         MOV    DX,07A5                  ; print "drive <d>"
  160.         CALL   0635
  161.         MOV    AL,02
  162.         JMP    05D4                     ; return to DOS with code 2
  163. }
  164.  
  165. command_bad()
  166. {
  167. 05E9:   CALL   0608             ; command_missing();
  168.         JMP    03D6
  169. }
  170.  
  171. ; Save registers
  172. 05EF:   PUSH   DS
  173.         PUSH   BX
  174.         PUSH   AX
  175. ; Restore the original file handle 0
  176.         MOV    AH,51
  177.         INT    21
  178.         MOV    AX,[0930]        ; PSP:[18H] = [930]
  179.         MOV    DS,BX
  180.         MOV    [0018],AX
  181. ; Restore registers
  182.         POP    AX
  183.         POP    BX
  184.         POP    DS
  185.         RET
  186.  
  187. bad_command_interp()
  188. {
  189. 0602:   MOV    DX,08BC          ; print "Bad or missing command interpreter"
  190.         JMP    0302
  191. }
  192.  
  193. interp_missing()
  194. {
  195. 0608:   MOV    DX,082D
  196.         MOV    AL,[0965]
  197.         CALL   0468             ; get disk info using int21(19) and int 11
  198.         JNE    0602
  199.         CALL   0635             ; print message "Insert CMD.COM disk in"
  200.         MOV    DX,083D          ; if ([0965] == 0)
  201.         CMP    BYTE PTR [0965],00  ; print message "default drive"
  202.         JNE    0623             ; else
  203.         MOV    DX,0845          ;    print message "drive C"
  204. 0623:   CALL   0635
  205.         MOV    DX,0852          ; print message "And strike key when ready"
  206.         CALL   0635
  207.         MOV    AX,0C07          ; get the user's keystroke
  208.         INT    21
  209.         RET
  210. }
  211. ; ***************************************************************************
  212. ; *                   MESSAGE PRINTING ROUTINES
  213. ; ***************************************************************************
  214.  
  215. put_CR()
  216. {
  217. 632:    MOV    DX,07AD          ; put out a <CR>
  218.         print_message();
  219. }
  220.  
  221. ; This routine prints a (encoded) message to the terminal.
  222. ; If the message has a digit in it ('0'-'9'), then use the digit to index
  223. ;   into an array of submessage pointers starting at 701.
  224. print_message(dx)
  225. {
  226. 635:    PUSH   AX
  227.         PUSH   BX
  228.         PUSH   DX
  229.         PUSH   SI
  230.         MOV    SI,DX
  231. 63B:    LODSB
  232.         PUSH   AX               ; save the loaded char
  233.         AND    AL,7F            ; mask out high bits
  234.         CMP    AL,30            ; is char between '0' and '9'?
  235.         JB     0658             ; NO - print the character
  236.         CMP    AL,39
  237.         JA     0658
  238.         SUB    AL,30            ; AL = c - '0'
  239.         CBW                     ; make digit take up entire AX reg
  240.         SHL    AX,1             ; DX = submessage pointed to by 701[AX]
  241.         MOV    BX,0701
  242.         ADD    BX,AX
  243.         MOV    DX,[BX]
  244.         CALL   0635             ; call routine recursively print sub-message
  245.         JMP    065E             ;  other digits
  246.  
  247. 658:    MOV    DL,AL            ; DL has the character to print
  248.         MOV    AH,02            ; print the character
  249.         INT    21
  250. ; DOS turns on the high bit of the last char of the message in order to
  251. ; save on the terminating char ('\0' or '$'). If the high bit is not on,
  252. ; we continue to print the remaining chars of the message.
  253. 65E:    POP    AX               ; get the original character
  254.         TEST   AL,80            ; is the high bit on?
  255.         JE     063B             ; NO! print more characters
  256. ; Restore the registers.
  257.         POP    SI
  258.         POP    DX
  259.         POP    BX
  260.         POP    AX
  261.         RET
  262. }   CALL   0635
  263.         MOV    AX,0C07          ; get the user's keystroke
  264.         INT    21
  265.         RET
  266. }
  267. ; **************